/**
*@author: Miguel Soares de Lima @ 05-01-2009
*/
public with sharing class DiscussionOverviewController {
	
	public String tabControl;	
	public String paramAll = System.currentPageReference().getParameters().get('all'); 
	public DiscussionMemberController dmc = new DiscussionMemberController();
	public Boolean isLastMemberAdmin = false;
	//Current user id.
	public Id USERID = UserInfo.getUserId();
	//The forum list and the tab control.
	public List<TeamForums> discussionForumList = new List<TeamForums>();
	public boolean noForums;

   	//Set of Integers to control pagination
   	public Integer totalItemsNumber;
   	public Integer numberOfItemsToShow = 10;
   	public Integer cntPagination;
   	public Integer currentPagination = 1;
   	public Integer firstRow = 0;
   	//Set of Booleans to show or not prev / next links
   	public boolean prevPageLinkShow = false;
   	public boolean prevPageShow  = false;
   	public boolean nextPageLinkShow  = false;
   	public boolean nextPageShow  = false;
	public Integer rowsCodeCoverage = 300;
	
	/**
	* Constructor
	*/
	public DiscussionOverviewController (){ 
		constructorFunction();
	}
 
 	/**
	*@retrun bool is last member admin
	*/
	public Boolean getIsLastMemberAdmin (){
		return isLastMemberAdmin;
	}
		
	/**
	*Set User Id
	*@param Id
	*/
	public void setUserId(Id sID){
		USERID = sID;
	}
		
	/**
	* Get exit forums
	*@return Boolean
	*/
	public boolean getNoForums(){
		return noForums;
	}
	
	/**
	* Set param to retrive type of data
	*@param String
	*/
	public void setParamAll (String paramAll){
		this.paramAll = paramAll;
	}
	
	/**
	* Execute on construct for load forums
	*/
	public void constructorFunction () {
		/**
		* To show tabs, look at the param.
		*/
		
		if(paramAll == null || paramAll == 'myForums'){			
			discussionForumList = getDiscussionForums(USERID);
			tabControl = 'myForums';
		} else {
			discussionForumList = getDiscussionForums('');
			tabControl = 'allForums';	
		}
		
		totalItemsNumber = discussionForumList.size();
		if(totalItemsNumber == 0 ){
			noForums = true;
		} else {
			noForums = false;
		}
		genCntPagination();
		while (currentPagination > cntPagination) {
			currentPagination--;
   			firstRow = firstRow - ( noForums ? 0 : numberOfItemsToShow );
		}
	}
		
	/**
	* Returns tab control name
	*@return String
	*/
	public String getTabControl(){
		return tabControl;
	}
	
	/**
	* Returns TeamForums list
	*@return List<TeamForums>
	*/
	public List<TeamForums> getForums(){		
		return discussionForumList;
	}

	/**
	* Count paginator pages number.
	*/   
   	public void genCntPagination () {
   		cntPagination = (totalItemsNumber - (Math.mod(totalItemsNumber, numberOfItemsToShow)))/ numberOfItemsToShow;	
   		if (Math.mod(totalItemsNumber, numberOfItemsToShow) != 0 ) {
   			cntPagination++;
   		} 
   			
   	}
   	
   	/**
   	* Move to next page
   	*/
   	public void nextPage () {
   		currentPagination++;
   		firstRow = firstRow + numberOfItemsToShow;   		   		
   	}
   	
   	/**
   	* Move to previus page
   	*/
   	public void prevPage () {
   		currentPagination--;   		
   		firstRow = firstRow - numberOfItemsToShow;	
   		
   	}
   	
   	/**
   	* Move to last page
   	*/
   	public void lastPage () {
   		currentPagination = cntPagination;
   		Integer lastPageElementsCnt = Math.mod(totalItemsNumber, numberOfItemsToShow);
   		if (lastPageElementsCnt == 0){
   			lastPageElementsCnt = numberOfItemsToShow;
   		}

   		firstRow = totalItemsNumber - lastPageElementsCnt;   		
   		
   	}
   	
   	/**
   	* Move to first page
   	*/
   	public void firstPage () {
   		currentPagination = 1;   		
   		firstRow = 0;   		   		
   	}
   	
   	
   	/**
   	* Returns current pagination num
   	*@return Integer
   	*/
   	public Integer getCurrentPagination () {
   		return currentPagination;
   	}
   	
   	/**
   	* Get number of pages
   	*@return Integer
   	*/
   	public Integer getCntPagination () {
   		return cntPagination;
   	}
   	
   	/**
   	* Returns number of rows to show
   	*@return Integer
   	*/
   	public Integer getNumberOfItemsToShow () {
   		return numberOfItemsToShow;
   	}
   	
   	/**
   	* Returns current first row
   	/*@return Integer
   	*/
   	public Integer getFirstRow () {
   		return firstRow;
   	}
   	
   	/**
   	* Return boolean to show previus link
   	*@return Boolean
   	*/
	public boolean getPrevPageLinkShow () {
		if(currentPagination == 1){ 
			prevPageLinkShow = false;		
		} else {
			prevPageLinkShow = true;
		}
   		return prevPageLinkShow;
   	}
   	
   	/**
   	* Return boolean to show 
   	*@return Boolean
   	*/
   	public boolean getPrevPageShow () {
   		if(currentPagination == 1){	
   			prevPageShow = true; 
   		} else {
   			prevPageShow = false;
   		}
   		return prevPageShow;
   	}
   	
   	/**
   	* Returns boolean to show next page link
   	*@return Boolean
   	*/
   	public boolean getNextPageLinkShow () {
   		if((currentPagination == cntPagination) || (cntPagination == 0)){	
   			nextPageLinkShow = false; 
		} else { 
			nextPageLinkShow = true;
		}   		
   		return nextPageLinkShow;
   	}
   	
   	/**
   	* Returns boolean to show next page
   	*@return Boolean
   	*/
   	public boolean getNextPageShow () {
   		if((currentPagination == cntPagination) || (cntPagination == 0)){ 
   			nextPageShow = true; 
		} else { 
			nextPageShow = false;
		} 
   		return nextPageShow;
   	}

	/**
	* @param String userid The User Id, if not given , the method returns all the discussion forums available.
	* @return List<TeamForums> The list of Discussion Forums  
	*/	
	public List<TeamForums> getDiscussionForums(String idusr) {
		
		List<TeamForums> discussionForumList = new List<TeamForums>();
		List<User> teamAdmin = [Select Id, Profile.PermissionsModifyAllData From User where id =:USERID limit 1];
		
		/**
		* If parameter is not empty, return the list of teams.
		*/
		
		if(idusr != ''){
			/**
			* Get user team List with given ID
			*/
			
			List<DiscussionMember__c> discussionMember = [select Id, Name, DiscussionForum__c, User__c from DiscussionMember__c where User__c =:USERID and DiscussionForum__c != null];
			
			List<Id> DiscussionForumIds = new List<Id>();
			for(DiscussionMember__c temp: discussionMember){ 
				DiscussionForumIds.add(temp.DiscussionForum__c);
			}
			List<DiscussionForum__c> forumList = new List<DiscussionForum__c>();
			forumList = [select Name, Id, CreatedById, CreatedBy.Name, MessageCount__c, TopicCount__c, LastPostedMessage__c, PictureId__c, PublicProfile__c from DiscussionForum__c where Id in:(DiscussionForumIds)];
			
			Map<Id, String> userProfiles = new Map<Id, String>();
			for(DiscussionMember__c d: [select DiscussionForum__c, DiscussionProfile__r.Name from DiscussionMember__c where DiscussionForum__c in:DiscussionForumIds and User__c =:USERID]){
				userProfiles.put(d.DiscussionForum__c, d.DiscussionProfile__r.Name);
			}
			
			System.debug('\n************'+ forumList +'***************');
			
			if(forumList.size() >= 1 ){	
				try{
					
					for(DiscussionForum__c d:forumList){
						if ((d.Id != null) || (d.Id != '')){
							TeamForums discussionForumListItem = new TeamForums();
			                discussionForumListItem.setTeamId(d.Id);
							if(d.MessageCount__c == null)
								d.MessageCount__c = 0;
							discussionForumListItem.setNumberOfMessages(d.MessageCount__c);
							if(d.TopicCount__c == null)
								d.TopicCount__c = 0;
							discussionForumListItem.setNumberOfThreads(d.TopicCount__c);	
							discussionForumListItem.setTeamName(d.Name);
							discussionForumListItem.setCreatedByName(d.CreatedBy.Name);
							discussionForumListItem.setCreatedById(d.CreatedById);
							discussionForumListItem.setIsPublic(d.PublicProfile__c != null);
							discussionForumListItem.setIsMember(userProfiles.containsKey(d.Id));
							String nameProfileAdmin = 'DiscussionForum Administrator';
							discussionForumListItem.setIsAdmin(teamAdmin[0].Profile.PermissionsModifyAllData || nameProfileAdmin.equals(userProfiles.get(d.Id)));
							discussionForumListItem.setLastPostMessage(d.LastPostedMessage__c);
							discussionForumListItem.setPicture(d.PictureId__c);
							discussionForumList.add(discussionForumListItem);
						System.Debug('*************************');
						}
					}
				} catch (Exception e ){
					throw e;					
				}
			}
			
		} else {
			/**
			* All teams
			*/
			List<DiscussionForum__c> forumList = [Select Name, Id, CreatedById, CreatedBy.Name, MessageCount__c, TopicCount__c, LastPostedMessage__c, PictureId__c, PublicProfile__c From DiscussionForum__c ];
						
			List<Id> DiscussionForumIds = new List<Id>();
			for(DiscussionForum__c temp: forumList){ 
				DiscussionForumIds.add(temp.Id);
			}
			
			Map<Id, String> userProfiles = new Map<Id, String>();
			for(DiscussionMember__c d: [select DiscussionForum__c, DiscussionProfile__r.Name from DiscussionMember__c where DiscussionForum__c in:DiscussionForumIds and User__c =:USERID]){
				userProfiles.put(d.DiscussionForum__c, d.DiscussionProfile__r.Name);
			}
			
			for(DiscussionForum__c Id: forumList){	
				TeamForums discussionForumListItem = new TeamForums();
                discussionForumListItem.setTeamId(Id.Id);
				discussionForumListItem.setTeamName(Id.Name);
				if(Id.MessageCount__c == null)
					Id.MessageCount__c = 0;
				discussionForumListItem.setNumberOfMessages(Id.MessageCount__c);
				if(Id.TopicCount__c == null)
					Id.TopicCount__c = 0;
				discussionForumListItem.setIsPublic(Id.PublicProfile__c != null);
				discussionForumListItem.setIsMember(userProfiles.containsKey(Id.Id));
				discussionForumListItem.setCreatedById(Id.CreatedById);
				discussionForumListItem.setCreatedByName(Id.CreatedBy.Name );
				String nameProfileAdmin = 'DiscussionForum Administrator';
				discussionForumListItem.setIsAdmin(teamAdmin[0].Profile.PermissionsModifyAllData || nameProfileAdmin.equals(userProfiles.get(Id.Id)));
				discussionForumListItem.setNumberOfThreads(Id.TopicCount__c);	
				discussionForumListItem.setPicture(Id.PictureId__c);
				discussionForumListItem.setLastPostMessage(Id.LastPostedMessage__c);
				discussionForumList.add(discussionForumListItem);	
			}
		}
		
		return discussionForumList;
	}
	
	/**
	* Join to discussion forum
	*/
	public void joinForum(){
		dmc.setDiscussionId(System.currentPageReference().getParameters().get('fid'));
		dmc.joinForum();
	}
	
	/**
	* Unjoin to discussion forum
	*/
	public void unjoinForum(){
		dmc.setDiscussionId(System.currentPageReference().getParameters().get('fid'));
		if(!dmc.isLastMemberAdmin()){
			dmc.unjoinForum();
			isLastMemberAdmin = false;
		}else{
			isLastMemberAdmin = true;
		}
	}
	
	/**
	* Inner Class to show Discussion Forum Info.
	* @return String TeamName 
	* @return String TeamDescription 
	* @return Integer NumberOfMessages 
	* @return Integer NumberOfThreads
	* @return String LastPostMessage 
	*/
	public class TeamForums {
		
		String TeamId;
		String TeamName;
		String TeamDescription;
		String createdByName;
		String createdById;
		Integer NumberOfMessages;
		Integer NumberOfThreads;
		String LastPostMessage;
		String Picture;
		Boolean isAdmin;
   		Boolean isPublic;
   		Boolean isMember;
   		
		/**
		*@param sTeamId team id
		*/
		public void setTeamId(String sTeamId){
        	TeamId = sTeamId;
        }
        
    	/**
    	*@param sTeamName team name
    	*/
    	public void setTeamName(String sTeamName){
        	TeamName = sTeamName;
        }
        
        /**
        *@param sTeamDescription team description
        */
        public void setTeamDescription(String sTeamDescription){
    		if(sTeamDescription != null){
    			 if(sTeamDescription.length() > 70){
    			 	TeamDescription = sTeamDescription.substring(0,67) + '...';	
    			 	//Set full description for span title
    			 	fullDescription = sTeamDescription;
    			 }else {
    			 	TeamDescription = sTeamDescription;
    			 }
    		}else {
    			TeamDescription = '';
    		}
        }
        
        public String fullDescription {set; get;}
        
        /**
        *@param user id
        */
        public void setCreatedById( String id ){
        	createdById = id;
		}
		
		/**
		*@return String id
		*/
        public String getCreatedById(){
        	return createdById;
		}

        /**
        *@param user id
        */
        public void setCreatedByName( String name ){
        	createdByName = name;
		}
		
		/**
		*@return String id
		*/
        public String getCreatedByName(){
        	return createdByName;
		}

        /**
        *@param sNumberOfMessages number of messages
        */
        public void setNumberOfMessages(Double sNumberOfMessages){
        	NumberOfMessages = sNumberOfMessages.intValue();
        }

        /**
        *@param sNumberOfThreads number of threads
        */
        public void setNumberOfThreads(Double sNumberOfThreads){
        	NumberOfThreads = sNumberOfThreads.intValue();
        }
        
        /**
        *@param Boolean
        */
        public void setIsAdmin(Boolean is){
        	isAdmin = is;
        }
        
        /**
        *@param sLastPostMessage last posted message
        */
        public void setLastPostMessage(Id sLastPostMessage){
        	LastPostMessage = lastPostInfoString(sLastPostMessage);
        }
        
        /**
        *@param teamAvatar team avatar
        */
        public void setPicture(String teamAvatar){
        	Picture = teamAvatar;
        }
        
		/**
		*@return team id
		*/
		public String getTeamId() {
	    	return TeamId;
		}
		
        /**
        *@return team name
        */
        public String getTeamName() {
	    	return TeamName;
		}		
        
        /**
        *@return team description
        */
        public String getTeamDescription() {
	    	return TeamDescription;
		}
		
		/**
		*@return number of messages
		*/
		public Integer getNumberOfMessages() {
	    	return NumberOfMessages;
		}
		
		/**
		*@return number of threads
		*/
		public Integer getNumberOfThreads() {
	    	return NumberOfThreads;
		}
		
        /**
        * Return if current user is admin
        *@return Boolean
        */
        public Boolean getIsAdmin(){
        	return isAdmin;
        }
		
		/**
		*@return last posted message
		*/
		public String getLastPostMessage() {
	    	return LastPostMessage;
		}
		
		/**
		*@return team avatar
		*/
		public String getImage(){			
		  if(Picture == null)
		  	return '';
		  else
		  	return Picture;				
		}
		
		/**
   		*@param Boolean
   		*/
   		public void setIsPublic(Boolean isp){
   			this.isPublic = isp;
   		}
   		
   		/**
   		*@return Boolean
   		*/
   		public Boolean getIsPublic(){
   			return this.isPublic;
   		}
   		
   		/**
   		*@param Boolean
   		*/
   		public void setIsMember(Boolean ism){
   			this.isMember = ism;
   		}
   		
   		/**
   		*@return Boolean
   		*/
   		public Boolean getIsMember(){
   			return this.isMember;
   		}
   		
        /**
        * Set enable actions if is a manager or owner
        *@param String author Id
        *@param Boolean is manager
        
        public void setEnableActions(String sAuthorId, boolean isManager){        	
       		if(isManager){
				enableActions = true;
			} else {
				if(sAuthorId == UserInfo.getUserId()){
					enableActions = true;
				}
			}
        }
		*/
		/**
		* Method to convert dates.
		* @return String datestring The string of the lastest reply. 
		*/
		public String lastPostInfoString(Id dm){
			String lastPostString = '';
			String message = '';
			
			if (dm != null){
				List<DiscussionMessage__c> dms = new List<DiscussionMessage__c>();
				dms = [ Select 
						LastModifiedDate, 
						DiscussionTopic__r.Subject__c, 
						DiscussionTopic__c,
						PostedBy__r.Name, 
						PostedBy__r.Id,
						PostedBy__c From DiscussionMessage__c where id =: dm];
				DiscussionMessage__c d = dms[0];
				if(dms.size() > 0 && d.DiscussionTopic__r.Subject__c != null){

					Integer today = (System.now()).day();
					String dateInfo;
					
					if(today == (d.LastModifiedDate).day()){
						dateInfo = '本日 ' + (d.LastModifiedDate).format('HH:mm') + ' ' + (d.LastModifiedDate).format('aa');	
					} else {
						dateInfo = (d.LastModifiedDate).format('MM') + '/' + (d.LastModifiedDate).day() + ' ' +(d.LastModifiedDate).format('HH:mm') + ' ' + (d.LastModifiedDate).format('aa');
					}
					
					message = d.DiscussionTopic__r.Subject__c;
					
					if(message != null && message.length() > 25){
						message = message.substring(0,25) + '...';
					}
					
			 		lastPostString = ' ' + dateInfo + ' メッセージ:' + message + ' 投稿者:' + d.PostedBy__r.Name;
			 		System.debug('En este punto el dms es ' + dms.size() + ' y el message es ' + message);
				} else {
					lastPostString = 'このフォーラムには、まだメッセージが投稿されていません';
				}
			} else {
				lastPostString = 'このフォーラムには、まだメッセージが投稿されていません';
			}
			return lastPostString;
		}	
	}
	
	
	/**
	* Get rows for code coverage
	*@return Integer
	*/
	public Integer getrowsCodeCoverage(){
		return rowsCodeCoverage;
	} 
	
	/**
	* Set number of row (for code coverage use)
	*@param Integer
	*/
	public void setRowsCodeCoverage(Integer value){
		rowsCodeCoverage = value;
	}
	
	/**
	* Returns ActiveUser list
	*@return List<ActiveUser>
	*/
	public List<ActiveUser> getMostActiveUsers(){

		Date first = System.today().toStartOfWeek();
    	Datetime firstWeekDay = Datetime.newInstance(first.year(), first.month(), first.day(), 0, 0, 0);
    	Datetime lastWeekDay = firstWeekDay.addDays(7);
		Map<Id, ActiveUser> tempmap = new Map<Id, ActiveUser>();
		List<ActiveUser> mostActiveUsers = new List<ActiveUser>();
		Integer i;
		
		for(DiscussionForum__c disc : [ Select  
										Name, 
										Id,						
										MessageCount__c, 
										TopicCount__c,
										LastPostedMessage__c,
										CreatedDate,
										CreatedBy.Name,
										CreatedById
										From DiscussionForum__c
										limit : rowsCodeCoverage]){
			
			if(tempmap.containsKey(disc.CreatedById)){
				ActiveUser activeUser = tempmap.get(disc.CreatedById);
				Integer tempCount = activeUser.getMostActive() + 1;
				activeUser.setMostActive(tempCount); 
				tempmap.put(disc.CreatedById, activeUser);
			}else {
				ActiveUser activeUser = new ActiveUser();
				activeUser.setMostActive(1);
				activeUser.setId (disc.CreatedById);
				activeUser.setName(disc.CreatedBy.Name);
				tempmap.put(disc.CreatedById, activeUser);
			}
		}
		
		List<ActiveUser> activeUserList = tempmap.values();		 				
		this.sortResult(activeUserList);
		for(i = 0; i <= 5; i++ ){
			if(i < activeUserList.size()){
				activeUserList[i].commentCount();
				mostActiveUsers.add(activeUserList[i]);
			}
		}
		return mostActiveUsers;
	}
	
	/**
	* Returns ActiveUser sorted list
	*@param List<ActiveUser> unsorted list
	*@return List<ActiveUser> sorted list
	*/
	public List<ActiveUser> sortResult (List<ActiveUser> result) {
 		Integer n;
 		Integer i;
 		Integer j;
 		n = result.size() - 1;	
 		for (i = 1; i <= n; i++) {	
 			for (j = n; j >= i ; j--) {
 				if (result.get(j).getMostActive() >= result.get(j - 1).getMostActive()) {
 					ActiveUser tempActiveUser;
 					tempActiveUser = result.get(j - 1);
 					result.set(j - 1, result.get(j));
 					result.set(j, tempActiveUser); 	
 				}	
 			}
 		}
 		return result;
 	}	
 	
	
	/**
	* Class for encapsulate active Users instance 
	*/
	public class ActiveUser{
		
		public String userPicture;
		public Integer mostActive;
		public String name;
		public Integer commentsCount;
		public String id;
		public ActiveUser(){}
		public ActiveUser(String id){}
		
		/**
		* Returns messages count
		*/
		public void commentCount(){
			this.commentsCount = [Select count() From DiscussionMessage__c where PostedBy__c =: id];	
		}
		
		/**
		*@return number of most active users
		*/
		public Integer getMostActive(){
			return 	mostActive;
		}	
		
		/**
		*@return user name
		*/
		public String getName(){
			return 	name;
		}	
		
		/**
		*@return user id
		*/
		public String getId(){
			return 	id;
		}	
		
		/**
		*@return number of comments
		*/
		public Integer getCommentsCount(){
			return 	commentsCount;
		}
		
		/**
		*@return user avatar
		*/
		public String getPicture(){
			return this.userPicture;
		}
		
		/**
		*@param mActive num of most active users
		*/
		public void setMostActive(Integer mActive){
			mostActive = mActive;
		}
		
		/**
		*@param sName user name
		*/
		public void setName(String sName){
			name = sName;
		}
		
		/**
		*@param id user id
		*/
		public void setId(String id){
			this.id = id;
		}
		
		/**
		*@param countComments number of comments
		*/
		public void setCommentsCount(Integer countComments){
			commentsCount = countComments;
		}

	}

}